當我們要認識 Go 時,我們會遇到一系列問題,包含初始化(常數、變數)以及方法(數值、指針)等概念。這些概念是 Go 語言中的基本元素,了解它們將有助於我們撰寫讓自己與同事更看得清楚的程式碼。
constant
是一種 數值
或 識別符號
,在編譯時期就 已確定其值
,無法在運行時修改。常數通常用於代表在程式中 永遠不會改變
的 數值
或 標識
,以增強程式碼的 可讀性
和 維護性
。
Go 的常數有:
舉例:
package main
import "fmt"
func main() {
const (
// int / uint
MaxInt = int(^uint(0) >> 1)
// float64
Pi = 3.14159265359
// string
Version = "1.0.0"
// boolean
IsEnabled = true
)
fmt.Println("MaxInt:", MaxInt)
fmt.Println("Pi:", Pi)
fmt.Println("Version:", Version)
fmt.Println("IsEnabled:", IsEnabled)
}
MaxInt: 9223372036854775807
Pi: 3.14159265359
Version: 1.0.0
IsEnabled: true
var 可以聲明 一個
或 多個
變量,也可以簡短聲明 :=
聲明初始化的變量。
a := "apple"
fmt.Println(a) // apple
可以用 ()
初始化 var
var (
b, c int = 23, 44
d bool = false
f string = "dog"
)
fmt.Println("b, c: ", b, c)
fmt.Println("d:", d)
fmt.Println("f:", f)
聲明後 沒有給定初始值
,故印出零值。
var e int
fmt.Println(e) // 0
在程式碼執行初始化操作。每個 package
可以有一個或多個 init 函数,其用於設置package内的狀態、執行必要的初始化工作。
將 值
傳遞給 函數
或給 另一個變量
時,會複製原始的值,代表在 函數內部
或在 新的變數
中操作值的時候, 不會影響原始的值
。
num 的值依舊是 10 ,沒有改變
func increment(x int) {
x++
}
num := 10
increment(num)
而 Go 是使用 stack
的方式儲存 value
, stack
適用於儲存局部變量的內存,代表當聲明一個 value
類型的變量時,通常會分配在 stack
上,並在變量超出作用域時自動釋放。
但是因為在傳遞時會進行 複製
的行為,這樣會消耗太多的記憶體,可能會有性能的問題,因此在使用時,須衡量性能和內存需求。
*Pointer
用於儲存變數的 &地址
。 Pointer 變數指向另一個變數的 地址
,讓我们透過 pointer 間接呼叫與修改變量的值。Pointer 通常用於處理 函數參數
、 數據結構
、 內存管理
。簡單說,pointer 的用途是為了取得 value 。
func modifyValue(ptr *int) {
*ptr = 42 // 修改原始汴涼的值
}
func main() {
x := 10
modifyValue(&x) // 通過 pointer 傳遞 x 的地址
fmt.Println(x)
}
輸出 42
使用 pointer
可以 動態分配內存
,例如使用 new 函数或切片的 append 方法。
new
:動態分配
內存並 返回
指向內存的 pointer
,對於需要在運行時創建具 不確定大小
或 複雜結構的數據
非常有用。
ptr := new(int)
*ptr = 42
append
: slice
的 capicity
不足容納新元素時, append
可以增加內存,並將現有的元素複製到新內存中,接著返回指向新 slice
的 pointer
。
slice := []int{1, 2, 3}
slice = append(slice, 4)
自定義分配
:
使用 pointer
建立 自訂的資料結構
,在執行時可以 動態
的 增加
或 縮小
,以滿足程式的需求。
type Node struct {
Data int
Next *Node // 指向下一個 node 的 pointer
}
node1 := &Node{Data: 1}
node2 := &Node{Data: 2}
node1.Next = node2
謝天謝地今天生出 pointer ,看起來有點簡陋,還請見諒!